import {BaseSession} from './base'
import {BytesValue, FloatValue, fromAny} from "../proto";

export class AudioTrackSession extends BaseSession {
    private context: AudioContext;
    private lGain: GainNode;
    private rGain: GainNode;

    constructor(render: HTMLElement) {
        super('AudioTrack', render)
    }

    onCreate(sessionId: number, futureId: number, ...argv) {
        super.onCreate(sessionId, futureId, ...argv);
        this.initAudio()
    }

    private initAudio() {
        this.context = new AudioContext()
        this.lGain = this.context.createGain()
        this.rGain = this.context.createGain()
        this.lGain.gain.value = 1
        this.rGain.gain.value = 1
    }

    onDestroy() {
        super.onDestroy();
        this.context.suspend()
    }

    async onReceive(name: String, sessionId: number, futureId: number, ...argv) {
        switch (name) {
            case 'write':
                await this.write(...argv)
                return;
            case 'play':
                this.play()
                return;
            case 'stop':
                this.stop()
                return;
            case 'pause':
                this.pause()
                return;
            case 'setVolume':
                this.setVolume(...argv)
                return;
            case 'setSpeed':
                this.setSpeed(...argv)
                return;
        }
    }

    private async write(...argv) {
        const data = new Uint8Array(fromAny(argv[0], BytesValue))
        try {
            const audioBuffer = await this.context.decodeAudioData(data.buffer)
            const source = this.context.createBufferSource()
            source.buffer = audioBuffer

            const splitterNode = this.context.createChannelSplitter(2); // 创建声道分离处理器
            const merger = this.context.createChannelMerger(2); // 创建 合成器

            source.connect(splitterNode);
            splitterNode.connect(this.lGain, 0); //将分离器的 第0个通道给左声道
            splitterNode.connect(this.rGain, 1); //将分离器的 第1个通道给右声道
            this.lGain.connect(merger, 0, 0); //将左声道的第0个通道 给 合成器的第0个通道
            this.rGain.connect(merger, 0, 1); //将右声道的第0个通道 给 合成器的第1个通道
            merger.connect(this.context.destination);
            source.start(0)
            this.context.suspend()
        }catch (e){
            console.log(e)
        }
    }

    private play() {
        this.context.resume()
    }

    private stop() {
        this.context.suspend()
    }

    private pause() {
        this.context.suspend()
    }

    private setVolume(...argv: any[]) {
        const lv = fromAny(argv[0], FloatValue)
        const rv = argv.length > 1 ? fromAny(argv[1], FloatValue) : lv;

        this.lGain.gain.setValueAtTime(lv, this.context.currentTime)
        this.rGain.gain.setValueAtTime(rv, this.context.currentTime)
        this.context.resume()
    }

    private setSpeed(...argv: any[]) {

    }
}